// 这题的题意是如果选择了一个结点，就必须选择其所有祖宗结点
// 因此，可以用树形dp结合背包问题，先递归算出当结点的子节点为根的情况下所有情况的最大值
// 注意此时不能用状态表示选哪些子树，这是因为题目要求可能会有2^100的状态，一定会超时，所以可以用分组背包的方式进行优化
// 每个子树可以选择占用体积为0，1，2..., n种情况的体积，每种体积对应不同的价值，因此这个问题就变成了树形dp嵌套分组背包问题

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 110;
int f[N][N];
int a[N], w[N];
int h[N], e[N], ne[N], idx, root; // 我们需要自己找根节点
int n, m;

// 利用邻接表存图，把b作为a的子树
void add(int a, int b) { e[idx] = b, ne[idx] = h[a], h[a] = idx++; }

// left表示剩余容量
void dfs(int root, int left)
{
    if (left < a[root])
        return;
    // 体积为a[root]~left区间内都必须放进去
    for (int i = a[root]; i <= left; ++i)
        f[root][i] = w[root];

    for (int i = h[root]; ~i; i = ne[i])
    {
        int son = e[i];
        // cout << son << endl;
        dfs(son, left - a[root]);
        for (int j = left; j >= a[root]; --j)
        {
            for (int k = 0; k <= j - a[root]; ++k)
                f[root][j] = max(f[root][j], f[root][j - k] + f[son][k]);
        }
    }
}

int main()
{
    memset(h, -1, sizeof h);
    cin >> n >> m;
    for (int i = 1; i <= n; ++i)
    {
        int p;
        cin >> a[i] >> w[i] >> p;
        if (p == -1)
            root = i;
        else
            add(p, i);
    }
    // cout << root << ' ';
    dfs(root, m);
    cout << f[root][m] << endl;
    return 0;
}
